package com.example.demo.config.aspect;

import com.example.demo.config.annotation.TimeOutAnnotation;
import com.example.demo.result.BaseResult;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * @Author: njz
 * @Description:
 * @Date: create in 2022/7/4 16:00
 */
@Component
@Aspect
@Slf4j
public class TimeOutAspect {

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Around("@annotation(timeOutAnnotation)")
    public BaseResult around(ProceedingJoinPoint joinPoint, TimeOutAnnotation timeOutAnnotation){
        Future<Object> future = threadPoolTaskExecutor.submit(()->{
            try {
                return joinPoint.proceed();
            } catch (Throwable throwable) {
                log.error("线程执行出错",throwable);
                return null;
            }
        });
        try {
            future.get(5, TimeUnit.SECONDS);
            return BaseResult.result(200,"执行成功");
        } catch (InterruptedException e) {
            e.printStackTrace();
            return BaseResult.result(500,"执行失败");
        } catch (ExecutionException e) {
            e.printStackTrace();
            return BaseResult.result(500,"执行失败");
        } catch (TimeoutException e) {
            e.printStackTrace();
            log.warn("接口超时5秒");
            return BaseResult.result(500,"接口超时5秒");
        }

    }
}
